home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / wmesa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-28  |  46.1 KB  |  1,900 lines

  1. /*
  2.  *    File name    :    wmesa.c
  3.  *  Version        :    2.0
  4.  *
  5.  *  Display driver for Mesa 2.0  under 
  6.  *    Windows95, WindowsNT and Win32
  7.  *
  8.  *    Copyright (C) 1996-  Li Wei
  9.  *  Address        :        Institute of Artificial Intelligence
  10.  *                :            & Robotics
  11.  *                :        Xi'an Jiaotong University
  12.  *  Email        :        liwei@aiar.xjtu.edu.cn
  13.  *  Web page    :        http://sun.aiar.xjtu.edu.cn
  14.  *
  15.  *  This file and its associations are partially based on the 
  16.  *  Windows NT driver for Mesa, written by Mark Leaming
  17.  *  (mark@rsinc.com).
  18.  */
  19.  
  20. /*
  21.  * $Log: wmesa.c,v $
  22.  * Revision 2.0  1996/11/15 10:53:00 CST by Li Wei(liwei@aiar.xjtu.edu.cn)
  23.  * Initial revision
  24.  *
  25.  */
  26.  
  27. /*    NOTE: 
  28.  *    This driver also support stereo feature and parallel feature
  29.  *  If the above two features are desired, several other files
  30.  *  are needed and the definition of macro
  31.  *    NO_STEREO and
  32.  *    NO_PARALLEL
  33.  *    should be removed or commented
  34.  */
  35.  
  36. #define NO_PARALLEL
  37. #define NO_STEREO
  38.  
  39. #define WMESA_STEREO_C
  40.  
  41. #include <windows.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <wmesadef.h>
  45.  
  46. #include <GL\wmesa.h>
  47. #include "context.h"
  48. #include "dd.h"
  49. #include "xform.h"
  50. #include "vb.h"
  51. #include "matrix.h"
  52. #include "depth.h"
  53.  
  54. #ifdef PROFILE
  55.     #include "profile.h"
  56. #endif
  57.  
  58. #include <wing.h>
  59.  
  60.  
  61. /*#include "mesa_extend.h"*/
  62.  
  63. #if !defined(NO_STEREO)
  64.     
  65.     #include "gl\glu.h"
  66.     #include "stereo.h"
  67.     
  68.     PBYTE Buffer_Stereo;
  69.  
  70.     void WMesaCreateStereoBuffer(void);
  71.  
  72.     void WMesaInterleave( GLenum aView);
  73.  
  74.     void WMesaDestroyStereoBuffer(void);
  75.  
  76.     void WMesaShowStereo(GLuint list);
  77. #endif
  78. #if !defined(NO_PARALLEL)
  79.     #include "parallel.h"
  80. #endif
  81.  
  82. /* end of added code*/
  83.  
  84. /* Bit's used for dest: */
  85. #define FRONT_PIXMAP    1
  86. #define BACK_PIXMAP    2
  87. #define BACK_XIMAGE    4
  88.  
  89. static PWMC Current = NULL;
  90. WMesaContext WC = NULL;
  91.  
  92. #ifdef NDEBUG
  93.   #define assert(ignore)    ((void) 0)
  94. #else
  95.   void Mesa_Assert(void *Cond,void *File,unsigned Line)
  96.   {
  97.     char Msg[512];
  98.     sprintf(Msg,"%s %s %d",Cond,File,Line);
  99.     MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
  100.     exit(1);
  101.   }
  102.   #define assert(e)    if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
  103. #endif
  104.  
  105. #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
  106. #define DD_RELEASEDC
  107.  
  108. //#define BEGINGDICALL    if(Current->rgb_flag)wmFlushBits(Current);
  109. #define BEGINGDICALL
  110. //#define ENDGDICALL        if(Current->rgb_flag)wmGetBits(Current);
  111. #define ENDGDICALL
  112.  
  113. #define FLIP(Y)  (Current->height-(Y)-1)
  114.  
  115. #define STARTPROFILE 
  116. #define ENDPROFILE(PARA) 
  117.  
  118. static void FlushToFile(PWMC pwc, PSTR    szFile);
  119.  
  120. BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
  121.  
  122. BOOL wmDeleteBackingStore(PWMC pwc);
  123.  
  124. void wmCreatePalette( PWMC pwdc );
  125. BOOL wmSetDibColors(PWMC pwc);
  126. void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
  127.  
  128. void wmCreateDIBSection(
  129.     HDC     hDC,
  130.     PWMC pwc,    // handle of device context
  131.     CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data
  132.     UINT iUsage    // color data type indicator: RGB values or palette indices
  133.     );
  134.  
  135. BOOL wmFlush(PWMC pwc);
  136.  
  137. /*
  138.  * Useful macros:
  139.    Modified from file osmesa.c     
  140.  */
  141.  
  142. #define PIXELADDR(X,Y)  ((GLbyte *)Current->pbPixels + (Current->height-Y)* Current->ScanWidth + (X)*nBypp)
  143.  
  144.  
  145. /* Finish all pending operations and synchronize. */
  146. static void finish(GLcontext* ctx)
  147. {
  148.    /* no op */
  149. }
  150.  
  151.  
  152. //
  153. // We cache all gl draw routines until a flush is made
  154. //
  155. static void flush(GLcontext* ctx)
  156. {
  157.     STARTPROFILE
  158.     if(Current->rgb_flag && !(Current->dib.fFlushed)&&!(Current->db_flag)){
  159.         wmFlush(Current);
  160.     }
  161.     ENDPROFILE(flush)
  162.    
  163. }
  164.  
  165.  
  166.  
  167. /*
  168.  * Set the color index used to clear the color buffer.
  169.  */
  170. static void clear_index(GLcontext* ctx, GLuint index)
  171. {
  172.   STARTPROFILE
  173.   Current->clearpixel = index;
  174.   ENDPROFILE(clear_index)
  175. }
  176.  
  177.  
  178.  
  179. /*
  180.  * Set the color used to clear the color buffer.
  181.  */
  182. static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  183. {
  184.   STARTPROFILE
  185.   Current->clearpixel=RGB(r, g, b );
  186.   ENDPROFILE(clear_color)
  187. }
  188.  
  189.  
  190.  
  191. /*
  192.  * Clear the specified region of the color buffer using the clear color
  193.  * or index as specified by one of the two functions above.
  194.  */
  195. static void clear(GLcontext* ctx, 
  196.                   GLboolean all,GLint x, GLint y, GLint width, GLint height )
  197. {
  198.     DWORD    dwColor;    
  199.     WORD    wColor;
  200.     LPDWORD    lpdw = (LPDWORD)Current->pbPixels;
  201.     LPWORD    lpw = (LPWORD)Current->pbPixels;
  202.     LPBYTE    lpb = Current->pbPixels;
  203.  
  204.     STARTPROFILE
  205.  
  206.     if (all){
  207.         x=y=0;
  208.         width=Current->width;
  209.         height=Current->height;
  210.     }
  211.     if (Current->rgb_flag==GL_TRUE){
  212.         if(Current->db_flag==GL_TRUE){
  213.             UINT    nBypp = Current->cColorBits / 8;
  214.             int        i = 0;
  215.             int        iSize;
  216.  
  217.             if(nBypp == 2){
  218.                 iSize = (Current->width * Current->height) / nBypp;
  219.  
  220.                 wColor = BGR16(GetRValue(Current->clearpixel), 
  221.                                GetGValue(Current->clearpixel), 
  222.                                GetBValue(Current->clearpixel));
  223.                 dwColor = MAKELONG(wColor, wColor);
  224.             }
  225.             else if(nBypp == 4){
  226.                 iSize = (Current->width * Current->height);
  227.  
  228.                 dwColor = BGR32(GetRValue(Current->clearpixel), 
  229.                                GetGValue(Current->clearpixel), 
  230.                                GetBValue(Current->clearpixel));
  231.             }
  232.             //
  233.             // This is the 24bit case
  234.             //
  235.             else {
  236.  
  237.                 iSize = (Current->width * Current->height) / nBypp;
  238.  
  239.                 dwColor = BGR24(GetRValue(Current->clearpixel), 
  240.                                GetGValue(Current->clearpixel), 
  241.                                GetBValue(Current->clearpixel));
  242.  
  243.  
  244.                 while(i < iSize){
  245.                     *lpdw = dwColor;
  246.                     lpb += nBypp;
  247.                     lpdw = (LPDWORD)lpb;
  248.                     i++;
  249.                 }
  250.  
  251.     //            ENDPROFILE(clear)
  252.  
  253.                 return;
  254.             }
  255.  
  256.             while(i < iSize){
  257.                 *lpdw = dwColor;
  258.                 lpdw++;
  259.                 i++;
  260.             }
  261.         }
  262.         else{ // For single buffer
  263.          HDC DC=DD_GETDC;
  264.          HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
  265.          HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
  266.          HPEN Old_Pen=SelectObject(DC,Pen);
  267.          HBRUSH Old_Brush=SelectObject(DC,Brush);
  268.          Rectangle(DC,x,y,x+width,y+height);
  269.          SelectObject(DC,Old_Pen);
  270.          SelectObject(DC,Old_Brush);
  271.          DeleteObject(Pen);
  272.          DeleteObject(Brush);
  273.          DD_RELEASEDC;
  274.           }
  275.     }
  276.     else {
  277.         int i;
  278.         char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  279.         for (i=0; i<height; i++){
  280.             memset(Mem,Current->clearpixel,width);
  281.             Mem+=width;
  282.         }
  283.     }
  284.     ENDPROFILE(clear)
  285. }
  286.  
  287.  
  288.  
  289. /* Set the current color index. */
  290. static void set_index(GLcontext* ctx, GLuint index)
  291. {
  292.   STARTPROFILE
  293.   Current->pixel=index;
  294.   ENDPROFILE(set_index)
  295. }
  296.  
  297.  
  298.  
  299. /* Set the current RGBA color. */
  300. static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  301. {
  302.   STARTPROFILE
  303.   Current->pixel = RGB( r, g, b );
  304.   ENDPROFILE(set_color)
  305. }
  306.  
  307.  
  308.  
  309. /* Set the index mode bitplane mask. */
  310. static GLboolean index_mask(GLcontext* ctx, GLuint mask)
  311. {
  312.    /* can't implement */
  313.    return GL_FALSE;
  314. }
  315.  
  316.  
  317.  
  318. /* Set the RGBA drawing mask. */
  319. static GLboolean color_mask( GLcontext* ctx,
  320.                              GLboolean rmask, GLboolean gmask,
  321.                              GLboolean bmask, GLboolean amask)
  322. {
  323.    /* can't implement */
  324.    return GL_FALSE;
  325. }
  326.  
  327.  
  328.  
  329. /*
  330.  * Set the pixel logic operation.  Return GL_TRUE if the device driver
  331.  * can perform the operation, otherwise return GL_FALSE.  If GL_FALSE
  332.  * is returned, the logic op will be done in software by Mesa.
  333.  */
  334. GLboolean logicop( GLcontext* ctx, GLenum op )
  335. {
  336.    /* can't implement */
  337.    return GL_FALSE;
  338. }
  339.  
  340.  
  341. static void dither( GLcontext* ctx, GLboolean enable )
  342. {
  343.    /* No op */
  344. }
  345.  
  346.  
  347.  
  348. static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
  349. {
  350.    STARTPROFILE
  351.    /* TODO: this could be better */
  352.    if (mode==GL_FRONT || mode==GL_BACK) {
  353.       return GL_TRUE;
  354.    }
  355.    else {
  356.       return GL_FALSE;
  357.    }
  358.    ENDPROFILE(set_buffer)
  359. }
  360.  
  361.  
  362.  
  363. /* Return characteristics of the output buffer. */
  364. static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height /*, GLuint *depth */)
  365. {
  366.     
  367.     int New_Size;
  368.     RECT CR;
  369.     
  370.     STARTPROFILE
  371.     GetClientRect(Current->Window,&CR);
  372.  
  373.     *width=CR.right;
  374.     *height=CR.bottom;
  375. //    *depth = Current->depth;
  376.  
  377.     New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
  378.  
  379.     if (New_Size){
  380.         Current->width=*width;
  381.         Current->height=*height;
  382.         Current->ScanWidth=Current->width;
  383.         if ((Current->ScanWidth%sizeof(long))!=0)
  384.             Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
  385.  
  386.         if (Current->db_flag){
  387.             if (Current->rgb_flag==GL_TRUE){
  388.                 wmDeleteBackingStore(Current);
  389.                 wmCreateBackingStore(Current, Current->width, Current->height);
  390.             }
  391.             else{
  392.                 Current->ScanWidth=Current->width;
  393.                 if ((Current->ScanWidth%sizeof(long))!=0)
  394.                 Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
  395.                 
  396.                 Current->IndexFormat->bmiHeader.biWidth=Current->width;
  397.  
  398.                 if (Current->IndexFormat->bmiHeader.biHeight<0)
  399.                     Current->IndexFormat->bmiHeader.biHeight=-(Current->height);
  400.                 else
  401.                     Current->IndexFormat->bmiHeader.biHeight=Current->height;
  402.  
  403.                 Current->Compat_BM=WinGCreateBitmap(Current->dib.hDC,Current->IndexFormat,&((void *) Current->ScreenMem));
  404.  
  405.                 DeleteObject(SelectObject(Current->dib.hDC,Current->Compat_BM));
  406.             }
  407. //Code added by Li Wei to enable stereo display
  408. // Recreate stereo buffer when stereo_flag is TRUE while parallelFlag is FALSE
  409. #if !defined(NO_STEREO)
  410.             if(stereo_flag
  411. #if !defined(NO_PARALLEL)
  412.                 &&!parallelFlag
  413. #endif                
  414.                 ) {
  415.             if(stereoBuffer == GL_TRUE)
  416.                 WMesaDestroyStereoBuffer();
  417.             WMesaCreateStereoBuffer();
  418.             }
  419. #endif
  420. //    Resize OsmesaBuffer if in Parallel mode
  421. #if !defined(NO_PARALLEL)    
  422.             if(parallelFlag)
  423.             PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
  424.             Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);
  425. #endif
  426. //end modification        
  427.         
  428.         }
  429.     }
  430.  
  431.    ENDPROFILE(buffer_size)
  432. }
  433.  
  434.  
  435.  
  436. /**********************************************************************/
  437. /*****           Accelerated point, line, polygon rendering       *****/
  438. /**********************************************************************/
  439.  
  440.  
  441. static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
  442. {
  443.    GLuint i;
  444.  //  HDC DC=DD_GETDC;
  445.     PWMC    pwc = Current;
  446.      
  447.     STARTPROFILE
  448.  
  449.     if (Current->gl_ctx->VB->MonoColor) {
  450.       /* all drawn with current color */
  451.       for (i=first;i<=last;i++) {
  452.          if (Current->gl_ctx->VB->Unclipped[i]) {
  453.             int x, y;
  454.             x =       (GLint) Current->gl_ctx->VB->Win[i][0];
  455.             y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
  456.             wmSetPixel(pwc, y,x,GetRValue(Current->pixel), 
  457.                         GetGValue(Current->pixel), GetBValue(Current->pixel));
  458.          }
  459.       }
  460.    }
  461.    else {
  462.       /* draw points of different colors */
  463.       for (i=first;i<=last;i++) {
  464.          if (Current->gl_ctx->VB->Unclipped[i]) {
  465.             int x, y;
  466.             unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,
  467.                                     Current->gl_ctx->VB->Color[i][1]*255.0,
  468.                                     Current->gl_ctx->VB->Color[i][2]*255.0);
  469.             x =       (GLint) Current->gl_ctx->VB->Win[i][0];
  470.             y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
  471.             wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0, 
  472.                                     Current->gl_ctx->VB->Color[i][1]*255.0,
  473.                                     Current->gl_ctx->VB->Color[i][2]*255.0);
  474.          }
  475.       }
  476.    }
  477. //   DD_RELEASEDC;
  478.    ENDPROFILE(fast_rgb_points)
  479. }
  480.  
  481.  
  482.  
  483. /* Return pointer to accerated points function */
  484. extern points_func choose_points_function( GLcontext* ctx )
  485. {
  486.    STARTPROFILE
  487.    if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0
  488.        && !ctx->Texture.Enabled  && ctx->Visual->RGBAflag) {
  489.    ENDPROFILE(choose_points_function)
  490.       return fast_rgb_points;
  491.    }
  492.    else {
  493.    ENDPROFILE(choose_points_function)
  494.       return NULL;
  495.    }
  496. }
  497.  
  498.  
  499.  
  500. /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
  501. static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )
  502. {
  503.     STARTPROFILE
  504.     int x0, y0, x1, y1;
  505.     unsigned long pixel;
  506.     HDC DC=DD_GETDC;
  507.     HPEN Pen;
  508.     HPEN Old_Pen;
  509.  
  510.     if (Current->gl_ctx->VB->MonoColor) {
  511.       pixel = Current->pixel;  /* use current color */
  512.     }
  513.     else {
  514.       pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
  515.     }
  516.  
  517.     x0 =       (int) Current->gl_ctx->VB->Win[v0][0];
  518.     y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );
  519.     x1 =       (int) Current->gl_ctx->VB->Win[v1][0];
  520.     y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );
  521.  
  522.  
  523.     BEGINGDICALL
  524.  
  525.     Pen=CreatePen(PS_SOLID,1,pixel);
  526.     Old_Pen=SelectObject(DC,Pen);
  527.     MoveToEx(DC,x0,y0,NULL);
  528.     LineTo(DC,x1,y1);
  529.     SelectObject(DC,Old_Pen);
  530.     DeleteObject(Pen);
  531.     DD_RELEASEDC;
  532.  
  533.     ENDGDICALL
  534.  
  535.     ENDPROFILE(fast_flat_rgb_line)
  536. }
  537.  
  538.  
  539.  
  540. /* Return pointer to accerated line function */
  541. static line_func choose_line_function( GLcontext* ctx )
  542. {
  543.     STARTPROFILE
  544.    if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag
  545.        && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
  546.        && !ctx->Texture.Enabled && Current->rgb_flag) {
  547.    ENDPROFILE(choose_line_function)
  548.       return fast_flat_rgb_line;
  549.    }
  550.    else {
  551.    ENDPROFILE(choose_line_function)
  552.       return NULL;
  553.    }
  554. }
  555.  
  556. /**********************************************************************/
  557. /*****                 Optimized triangle rendering               *****/
  558. /**********************************************************************/
  559.  
  560.  
  561. /*
  562.  * Smooth-shaded, z-less triangle, RGBA color.
  563.  */
  564. static void smooth_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  565.                                      GLuint v2, GLuint pv )
  566. {
  567. UINT    nBypp = Current->cColorBits / 8;
  568. GLbyte* img;
  569. GLushort* img16;
  570. GLuint *img24 ,*img32;
  571. #define INTERP_Z 1
  572. #define INTERP_RGB 1
  573. #define INTERP_ALPHA 1
  574. #define INNER_LOOP( LEFT, RIGHT, Y )                            \
  575. {                                                                \
  576.    GLint i, len = RIGHT-LEFT;                                    \
  577.    img = PIXELADDR(LEFT,Y);                                       \
  578.    for (i=0;i<len;i++,img+=nBypp) {                                \
  579.       GLdepth z = FixedToDepth(ffz);                            \
  580.       if (z < zRow[i]) {                                        \
  581.          img16 = img24 = img32 = img;                            \
  582.          if(nBypp == 2)                                            \
  583.             *img16 = BGR16(    FixedToInt(ffr), FixedToInt(ffg),    \
  584.                             FixedToInt(ffb));                    \
  585.          if(nBypp == 3)                                            \
  586.             *img24 = BGR24(    FixedToInt(ffr), FixedToInt(ffg),    \
  587.                             FixedToInt(ffb));                    \
  588.             if(nBypp == 4)                                            \
  589.             *img32 = BGR32(    FixedToInt(ffr), FixedToInt(ffg),    \
  590.                             FixedToInt(ffb));                    \
  591.          zRow[i] = z;                                            \
  592.       }                                                            \
  593.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;  ffa += fdadx;\
  594.       ffz += fdzdx;                                                \
  595.    }                                                            \
  596. }
  597.     
  598.     #include "tritemp.h"
  599.  }
  600.  
  601.  
  602.  
  603.  
  604. /*
  605.  * Flat-shaded, z-less triangle, RGBA color.
  606.  */
  607. static void flat_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  608.                                    GLuint v2, GLuint pv )
  609. {
  610. GLbyte* img;
  611. GLushort* img16;
  612. GLuint *img24, *img32;
  613. UINT    nBypp = Current->cColorBits / 8;
  614. GLubyte r, g, b ;
  615. GLushort pixel16 = BGR16(r,g,b);
  616. GLuint   pixel24 = BGR24(r,g,b);
  617. GLuint   pixel32 = BGR32(r,g,b);
  618.  
  619. #define INTERP_Z 1
  620. #define SETUP_CODE            \
  621.    r = VB->Color[pv][0];    \
  622.    g = VB->Color[pv][1];    \
  623.    b = VB->Color[pv][2];    
  624.  
  625. #define INNER_LOOP( LEFT, RIGHT, Y )                            \
  626. {                                                                \
  627.    GLint i, len = RIGHT-LEFT;                                    \
  628.    img = PIXELADDR(LEFT,Y);                                        \
  629.    for (i=0;i<len;i++,img+=nBypp) {                                \
  630.       GLdepth z = FixedToDepth(ffz);                            \
  631.       if (z < zRow[i]) {                                        \
  632.          img16 = img24 = img32 = img;                            \
  633.          if(nBypp == 2)                                            \
  634.             *img16 = pixel16;                                    \
  635.          if(nBypp == 3)                                            \
  636.             *img24 = pixel24;                                    \
  637.             if(nBypp == 4)                                            \
  638.             *img32 = pixel32;                                    \
  639.          zRow[i] = z;                                            \
  640.       }                                                            \
  641.       ffz += fdzdx;                                                \
  642.    }                                                            \
  643. }
  644.  
  645. #include "tritemp.h"
  646. }
  647.  
  648.  
  649.  
  650. /*
  651.  * Return pointer to an accelerated triangle function if possible.
  652.  */
  653. static triangle_func choose_triangle_function( GLcontext *ctx )
  654. {
  655.    if (ctx->Polygon.SmoothFlag)     return NULL;
  656.    if (ctx->Polygon.StippleFlag)    return NULL;
  657.    if (ctx->Texture.Enabled)        return NULL;
  658.  
  659.    if (ctx->RasterMask==DEPTH_BIT
  660.        && ctx->Depth.Func==GL_LESS
  661.        && ctx->Depth.Mask==GL_TRUE
  662.        && ctx->Visual->RGBAflag) {  
  663.     if (ctx->Light.ShadeModel==GL_SMOOTH) {
  664.          return smooth_color_z_triangle;
  665.       }
  666.       else {
  667.          return flat_color_z_triangle;
  668.       }
  669.    }
  670.    return NULL;
  671. }
  672.  
  673.  
  674. /* Draw a convex polygon using color Current->gl_ctx->VB->Color[pv] */
  675. static void fast_flat_rgb_polygon( GLcontext* ctx, GLuint n, GLuint vlist[], GLuint pv )
  676. {
  677.    STARTPROFILE
  678.    POINT *Pts=(POINT *) malloc(n*sizeof(POINT));
  679.    HDC DC=DD_GETDC;
  680.    HPEN Pen;
  681.    HBRUSH Brush;
  682.    HPEN Old_Pen;
  683.    HBRUSH Old_Brush;
  684.    GLint pixel;
  685.    GLuint i;
  686.  
  687.    if (Current->gl_ctx->VB->MonoColor) {
  688.       pixel = Current->pixel;  /* use current color */
  689.    }
  690.    else {
  691.       pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
  692.    }
  693.  
  694.    Pen=CreatePen(PS_SOLID,1,pixel);
  695.    Brush=CreateSolidBrush(pixel);
  696.    Old_Pen=SelectObject(DC,Pen);
  697.    Old_Brush=SelectObject(DC,Brush);
  698.  
  699.    for (i=0; i<n; i++) {
  700.       int j = vlist[i];
  701.       Pts[i].x =       (int) Current->gl_ctx->VB->Win[j][0];
  702.       Pts[i].y = FLIP( (int) Current->gl_ctx->VB->Win[j][1] );
  703.    }
  704.  
  705.    BEGINGDICALL
  706.  
  707.    Polygon(DC,Pts,n);
  708.    SelectObject(DC,Old_Pen);
  709.    SelectObject(DC,Old_Brush);
  710.    DeleteObject(Pen);
  711.    DeleteObject(Brush);
  712.    DD_RELEASEDC;
  713.    free(Pts);
  714.  
  715.    ENDGDICALL
  716.  
  717.   ENDPROFILE(fast_flat_rgb_polygon)
  718. }
  719.  
  720.  
  721.  
  722. /* Return pointer to accerated polygon function */
  723. static polygon_func choose_polygon_function( GLcontext* ctx )
  724. {
  725.     STARTPROFILE
  726.    if (!ctx->Polygon.SmoothFlag && !ctx->Polygon.StippleFlag
  727.        && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
  728.        && !ctx->Texture.Enabled && Current->rgb_flag==GL_TRUE) {
  729.    ENDPROFILE(choose_polygon_function)
  730.       return fast_flat_rgb_polygon;
  731.    }
  732.    else {
  733.    ENDPROFILE(choose_polygon_function)
  734.       return NULL;
  735.    }
  736. }
  737.  
  738.  
  739.  
  740. /**********************************************************************/
  741. /*****                 Span-based pixel drawing                   *****/
  742. /**********************************************************************/
  743.  
  744.  
  745. /* Write a horizontal span of color-index pixels with a boolean mask. */
  746. static void write_index_span( GLcontext* ctx, 
  747.                               GLuint n, GLint x, GLint y,
  748.                               const GLuint index[],
  749.                               const GLubyte mask[] )
  750. {
  751.       STARTPROFILE
  752.       GLuint i;
  753.       char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  754.       assert(Current->rgb_flag==GL_FALSE);
  755.       for (i=0; i<n; i++)
  756.         if (mask[i])
  757.           Mem[i]=index[i];
  758.        ENDPROFILE(write_index_span)
  759. }
  760.  
  761.  
  762.  
  763. /*
  764.  * Write a horizontal span of pixels with a boolean mask.  The current
  765.  * color index is used for all pixels.
  766.  */
  767. static void write_monoindex_span(GLcontext* ctx, 
  768.                                  GLuint n,GLint x,GLint y,
  769.                                  const GLubyte mask[])
  770. {
  771.       STARTPROFILE
  772.       GLuint i;
  773.       char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  774.       assert(Current->rgb_flag==GL_FALSE);
  775.       for (i=0; i<n; i++)
  776.         if (mask[i])
  777.           Mem[i]=Current->pixel;
  778.       ENDPROFILE(write_monoindex_span)
  779. }
  780.  
  781. /*
  782.     To improve the performance of this routine, frob the data into an actual scanline
  783.     and call bitblt on the complete scan line instead of SetPixel.
  784. */
  785.  
  786. /* Write a horizontal span of color pixels with a boolean mask. */
  787. static void write_color_span( GLcontext* ctx, 
  788.               GLuint n, GLint x, GLint y,
  789.               const GLubyte
  790.               red[], const GLubyte green[],
  791.               const GLubyte blue[], const GLubyte alpha[],
  792.               const GLubyte mask[] )
  793. {
  794.     STARTPROFILE
  795.  
  796.     PWMC    pwc = Current;
  797.  
  798.     if (pwc->rgb_flag==GL_TRUE)
  799.     {
  800.         GLuint i;
  801.         HDC DC=DD_GETDC;
  802.         y=FLIP(y);
  803.  
  804.         if (mask) {
  805.             for (i=0; i<n; i++)
  806.                 if (mask[i])
  807.                     wmSetPixel(pwc, y, x + i,red[i], green[i], blue[i]);
  808.         }
  809.  
  810.         else {
  811.             for (i=0; i<n; i++)
  812.                 wmSetPixel(pwc, y, x + i, red[i], green[i], blue[i]);
  813.         }
  814.  
  815.         DD_RELEASEDC;
  816.  
  817.     }
  818.  
  819.   else
  820.   {
  821.         GLuint i;
  822.         char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  823.         if (mask) {
  824.            for (i=0; i<n; i++)
  825.              if (mask[i])
  826.                Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
  827.         }
  828.         else {
  829.            for (i=0; i<n; i++)
  830.              Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
  831.             }
  832.     }
  833.    ENDPROFILE(write_color_span)
  834.  
  835. }
  836.  
  837. /*
  838.  * Write a horizontal span of pixels with a boolean mask.  The current color
  839.  * is used for all pixels.
  840.  */
  841. static void write_monocolor_span( GLcontext* ctx, 
  842.                                   GLuint n, GLint x, GLint y,
  843.                                   const GLubyte mask[])
  844. {
  845.   STARTPROFILE
  846.   GLuint i;
  847.   HDC DC=DD_GETDC;
  848.   PWMC    pwc = Current;
  849.  
  850.   assert(Current->rgb_flag==GL_TRUE);
  851.   y=FLIP(y);
  852.  
  853.   if(Current->rgb_flag==GL_TRUE){
  854.       for (i=0; i<n; i++)
  855.         if (mask[i])
  856. // Trying
  857.         wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
  858.   }
  859.   else {
  860.       for (i=0; i<n; i++)
  861.         if (mask[i])
  862.             SetPixel(DC, y, x+i, Current->pixel);
  863.   }
  864.  
  865.     DD_RELEASEDC;
  866.  
  867.     ENDPROFILE(write_monocolor_span)
  868. }
  869.  
  870.  
  871.  
  872. /**********************************************************************/
  873. /*****                   Array-based pixel drawing                *****/
  874. /**********************************************************************/
  875.  
  876.  
  877. /* Write an array of pixels with a boolean mask. */
  878. static void write_index_pixels( GLcontext* ctx, 
  879.                                 GLuint n, const GLint x[], const GLint y[],
  880.                                 const GLuint index[], const GLubyte mask[] )
  881. {
  882.    STARTPROFILE
  883.    GLuint i;
  884.    assert(Current->rgb_flag==GL_FALSE);
  885.    for (i=0; i<n; i++) {
  886.       if (mask[i]) {
  887.          char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
  888.            *Mem = index[i];
  889.       }
  890.    }
  891.    ENDPROFILE(write_index_pixels)
  892. }
  893.  
  894.  
  895.  
  896. /*
  897.  * Write an array of pixels with a boolean mask.  The current color
  898.  * index is used for all pixels.
  899.  */
  900. static void write_monoindex_pixels( GLcontext* ctx, 
  901.                                     GLuint n,
  902.                                     const GLint x[], const GLint y[],
  903.                                     const GLubyte mask[] )
  904. {
  905.    STARTPROFILE
  906.    GLuint i;
  907.    assert(Current->rgb_flag==GL_FALSE);
  908.    for (i=0; i<n; i++) {
  909.       if (mask[i]) {
  910.          char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
  911.             *Mem = Current->pixel;
  912.       }
  913.    }
  914.    ENDPROFILE(write_monoindex_pixels)
  915. }
  916.  
  917.  
  918.  
  919. /* Write an array of pixels with a boolean mask. */
  920. static void write_color_pixels( GLcontext* ctx,
  921.                                 GLuint n, const GLint x[], const GLint y[],
  922.                                 const GLubyte r[], const GLubyte g[],
  923.                                 const GLubyte b[], const GLubyte a[],
  924.                                 const GLubyte mask[] )
  925. {
  926.     STARTPROFILE
  927.     GLuint i;
  928.     PWMC    pwc = Current;
  929.     HDC DC=DD_GETDC;
  930.     assert(Current->rgb_flag==GL_TRUE);
  931.     for (i=0; i<n; i++)
  932.         if (mask[i])
  933.             wmSetPixel(pwc, FLIP(y[i]),x[i],r[i],g[i],b[i]);
  934.     DD_RELEASEDC;
  935.     ENDPROFILE(write_color_pixels)
  936. }
  937.  
  938.  
  939.  
  940. /*
  941.  * Write an array of pixels with a boolean mask.  The current color
  942.  * is used for all pixels.
  943.  */
  944. static void write_monocolor_pixels( GLcontext* ctx,
  945.                                     GLuint n,
  946.                                     const GLint x[], const GLint y[],
  947.                                     const GLubyte mask[] )
  948. {
  949.     STARTPROFILE
  950.     GLuint i;
  951.     PWMC    pwc = Current;
  952.     HDC DC=DD_GETDC;
  953.     assert(Current->rgb_flag==GL_TRUE);
  954.     for (i=0; i<n; i++)
  955.         if (mask[i])
  956.             wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel), 
  957.                         GetGValue(Current->pixel), GetBValue(Current->pixel));
  958.     DD_RELEASEDC;
  959.     ENDPROFILE(write_monocolor_pixels)
  960. }
  961.  
  962.  
  963.  
  964. /**********************************************************************/
  965. /*****            Read spans/arrays of pixels                     *****/
  966. /**********************************************************************/
  967.  
  968.  
  969. /* Read a horizontal span of color-index pixels. */
  970. static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[])
  971. {
  972.   STARTPROFILE
  973.   GLuint i;
  974.   char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  975.   assert(Current->rgb_flag==GL_FALSE);
  976.   for (i=0; i<n; i++)
  977.     index[i]=Mem[i];
  978.   ENDPROFILE(read_index_span)
  979.  
  980. }
  981.  
  982.  
  983.  
  984.  
  985. /* Read an array of color index pixels. */
  986. static void read_index_pixels( GLcontext* ctx, 
  987.                                GLuint n, const GLint x[], const GLint y[],
  988.                                GLuint indx[], const GLubyte mask[] )
  989. {
  990.    STARTPROFILE
  991.    GLuint i;
  992.   assert(Current->rgb_flag==GL_FALSE);
  993.   for (i=0; i<n; i++) {
  994.      if (mask[i]) {
  995.         indx[i]=*(Current->ScreenMem+y[i]*Current->ScanWidth+x[i]);
  996.      }
  997.   }
  998.    ENDPROFILE(read_index_pixels)
  999. }
  1000.  
  1001.  
  1002.  
  1003. /* Read a horizontal span of color pixels. */
  1004. static void read_color_span( GLcontext* ctx, 
  1005.                              GLuint n, GLint x, GLint y,
  1006.                              GLubyte red[], GLubyte green[],
  1007.                              GLubyte blue[], GLubyte alpha[] )
  1008. {
  1009.    STARTPROFILE
  1010.   UINT i;
  1011.   COLORREF Color;
  1012.   HDC DC=DD_GETDC;
  1013.   assert(Current->rgb_flag==GL_TRUE);
  1014.   y=FLIP(y);
  1015.   for (i=0; i<n; i++)
  1016.   {
  1017.     Color=GetPixel(DC,x+i,y);
  1018.     red[i]=GetRValue(Color);
  1019.     green[i]=GetGValue(Color);
  1020.     blue[i]=GetBValue(Color);
  1021.     alpha[i]=255;
  1022.   }
  1023.   DD_RELEASEDC;
  1024.   memset(alpha,0,n*sizeof(GLint));
  1025.    ENDPROFILE(read_color_span)
  1026. }
  1027.  
  1028.  
  1029. /* Read an array of color pixels. */
  1030. static void read_color_pixels( GLcontext* ctx,
  1031.                                GLuint n, const GLint x[], const GLint y[],
  1032.                                GLubyte red[], GLubyte green[],
  1033.                                GLubyte blue[], GLubyte alpha[],
  1034.                                const GLubyte mask[] )
  1035. {
  1036.    STARTPROFILE
  1037.   GLuint i;
  1038.   COLORREF Color;
  1039.   HDC DC=DD_GETDC;
  1040.   assert(Current->rgb_flag==GL_TRUE);
  1041.   for (i=0; i<n; i++) {
  1042.      if (mask[i]) {
  1043.         Color=GetPixel(DC,x[i],FLIP(y[i]));
  1044.         red[i]=GetRValue(Color);
  1045.         green[i]=GetGValue(Color);
  1046.         blue[i]=GetBValue(Color);
  1047.         alpha[i]=255;
  1048.      }
  1049.   }
  1050.   DD_RELEASEDC;
  1051.   memset(alpha,0,n*sizeof(GLint));
  1052.    ENDPROFILE(read_color_pixels)
  1053. }
  1054.  
  1055.  
  1056.  
  1057. /**********************************************************************/
  1058. /**********************************************************************/
  1059.  
  1060.  
  1061.  
  1062. void setup_DD_pointers( GLcontext* ctx )
  1063. {
  1064.    ctx->Driver.Finish = finish;
  1065.    ctx->Driver.Flush = flush;
  1066.  
  1067.    ctx->Driver.ClearIndex = clear_index;
  1068.    ctx->Driver.ClearColor = clear_color;
  1069.    ctx->Driver.Clear = clear;
  1070.  
  1071.    ctx->Driver.Index = set_index;
  1072.    ctx->Driver.Color = set_color;
  1073.    ctx->Driver.IndexMask = index_mask;
  1074.    ctx->Driver.ColorMask = color_mask;
  1075.  
  1076.    ctx->Driver.LogicOp = logicop;
  1077.    ctx->Driver.Dither = dither;
  1078.  
  1079.    ctx->Driver.SetBuffer = set_buffer;
  1080.    ctx->Driver.GetBufferSize = buffer_size;
  1081.  
  1082.    ctx->Driver.PointsFunc = choose_points_function(ctx);
  1083.    ctx->Driver.LineFunc = choose_line_function(ctx);
  1084.    ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
  1085.    //   ctx->Driver.TriangleFunc = choose_polygon_function(ctx);
  1086.  
  1087.    /* Pixel/span writing functions: */
  1088.    ctx->Driver.WriteColorSpan       = write_color_span;
  1089.    ctx->Driver.WriteMonocolorSpan   = write_monocolor_span;
  1090.    ctx->Driver.WriteColorPixels     = write_color_pixels;
  1091.    ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
  1092.    ctx->Driver.WriteIndexSpan       = write_index_span;
  1093.    ctx->Driver.WriteMonoindexSpan   = write_monoindex_span;
  1094.    ctx->Driver.WriteIndexPixels     = write_index_pixels;
  1095.    ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
  1096.  
  1097.    /* Pixel/span reading functions: */
  1098.    ctx->Driver.ReadIndexSpan = read_index_span;
  1099.    ctx->Driver.ReadColorSpan = read_color_span;
  1100.    ctx->Driver.ReadIndexPixels = read_index_pixels;
  1101.    ctx->Driver.ReadColorPixels = read_color_pixels;
  1102. }
  1103.  
  1104. //
  1105. // MesaGL32 is the DLL version of MesaGL for Win32
  1106. //
  1107.  
  1108. /**********************************************************************/
  1109. /*****                  WMesa API Functions                       *****/
  1110. /**********************************************************************/
  1111.  
  1112.  
  1113.  
  1114. #define PAL_SIZE 256
  1115. static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
  1116. {
  1117.    STARTPROFILE
  1118.     int i;
  1119.     HDC hdc;
  1120.     struct
  1121.     {
  1122.         WORD Version;
  1123.         WORD NumberOfEntries;
  1124.         PALETTEENTRY aEntries[PAL_SIZE];
  1125.     } Palette =
  1126.     {
  1127.         0x300,
  1128.         PAL_SIZE
  1129.     };
  1130.     hdc=GetDC(NULL);
  1131.     if (Pal!=NULL)
  1132.     GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
  1133.   else
  1134.     GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
  1135.     if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
  1136.     {
  1137.         for(i = 0; i <PAL_SIZE; i++)
  1138.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1139.         Palette.aEntries[255].peRed = 255;
  1140.         Palette.aEntries[255].peGreen = 255;
  1141.         Palette.aEntries[255].peBlue = 255;
  1142.         Palette.aEntries[255].peFlags = 0;
  1143.         Palette.aEntries[0].peRed = 0;
  1144.         Palette.aEntries[0].peGreen = 0;
  1145.         Palette.aEntries[0].peBlue = 0;
  1146.         Palette.aEntries[0].peFlags = 0;
  1147.     }
  1148.     else
  1149.     {
  1150.         int nStaticColors;
  1151.         int nUsableColors;
  1152.         nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
  1153.         for (i=0; i<nStaticColors; i++)
  1154.             Palette.aEntries[i].peFlags = 0;
  1155.         nUsableColors = PAL_SIZE-nStaticColors;
  1156.         for (; i<nUsableColors; i++)
  1157.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1158.         for (; i<PAL_SIZE-nStaticColors; i++)
  1159.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1160.         for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
  1161.             Palette.aEntries[i].peFlags = 0;
  1162.     }
  1163.     ReleaseDC(NULL,hdc);
  1164.   for (i=0; i<PAL_SIZE; i++)
  1165.   {
  1166.     aRGB[i].rgbRed=Palette.aEntries[i].peRed;
  1167.     aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
  1168.     aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
  1169.     aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
  1170.   }
  1171.         ENDPROFILE(GetPalette)
  1172. }
  1173.  
  1174.  
  1175. WMesaContext /*APIENTRY*/ WMesaCreateContext( HWND hWnd, HPALETTE Pal, 
  1176.                                              /*HDC hDC,*/ GLboolean rgb_flag,
  1177.                                               GLboolean db_flag )
  1178. {
  1179.   BITMAPINFO *Rec;
  1180.   //HDC DC;
  1181.   RECT CR;
  1182.   WMesaContext c;
  1183.    
  1184.   c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
  1185.   if (!c)
  1186.     return NULL;
  1187.  
  1188.   c->Window=hWnd;
  1189.   c->hDC = GetDC(hWnd);
  1190.   
  1191.   if (rgb_flag==GL_FALSE)
  1192.   {
  1193.     c->rgb_flag = GL_FALSE;
  1194.     c->pixel = 1;
  1195.     db_flag=GL_TRUE; // WinG requires double buffering
  1196.     //c->gl_ctx->BufferDepth = windepth;
  1197.   }
  1198.   else
  1199.   {
  1200.     c->rgb_flag = GL_TRUE;
  1201.     c->pixel = 0;
  1202.   }
  1203.   GetClientRect(c->Window,&CR);
  1204.   c->width=CR.right;
  1205.   c->height=CR.bottom;
  1206.   if (db_flag)
  1207.   {
  1208.     c->db_flag = 1;
  1209. //    c->hDC GetDC(c->Window);   
  1210.     /* Double buffered */
  1211.     if (c->rgb_flag==GL_TRUE)
  1212.     {
  1213.       //DC = c->hDC = hDC;
  1214.        
  1215. //        DC = c->hDC = GetDC(c->Window);
  1216.         wmCreateBackingStore(c, c->width, c->height);
  1217. //        ReleaseDC(c->Window,DC);
  1218.     }
  1219.     else
  1220.     {
  1221.       c->dib.hDC=WinGCreateDC();
  1222.       Rec=(BITMAPINFO *) malloc(sizeof(BITMAPINFO)+(PAL_SIZE-1)*sizeof(RGBQUAD));
  1223.       c->hPal=Pal;
  1224.       GetPalette(Pal,Rec->bmiColors);
  1225.       WinGRecommendDIBFormat(Rec);
  1226.       Rec->bmiHeader.biWidth=c->width;
  1227.       Rec->bmiHeader.biHeight*=c->height;
  1228.       Rec->bmiHeader.biClrUsed=PAL_SIZE;
  1229.       if (Rec->bmiHeader.biPlanes!=1 || Rec->bmiHeader.biBitCount!=8)
  1230.       {
  1231.         MessageBox(NULL,"Error.","This code presumes a 256 color, single plane, WinG Device.\n",MB_OK);
  1232.         exit(1);
  1233.       }
  1234.       c->Compat_BM=WinGCreateBitmap(c->dib.hDC,Rec,&((void *) c->ScreenMem));
  1235.       c->Old_Compat_BM=SelectObject(c->dib.hDC,c->Compat_BM);
  1236.       WinGSetDIBColorTable(c->dib.hDC,0,PAL_SIZE,Rec->bmiColors);
  1237.       c->IndexFormat=Rec;
  1238.       c->ScanWidth=c->width;
  1239.       c->cColorBits = 8;
  1240.       if ((c->ScanWidth%sizeof(long))!=0)
  1241.         c->ScanWidth+=(sizeof(long)-(c->ScanWidth%sizeof(long)));
  1242.     }
  1243.   }
  1244.   else
  1245.   {
  1246.     /* Single Buffered */
  1247.     c->db_flag = 0;
  1248.  
  1249. //    wmCreateBackingStore(c, c->width, c->height);
  1250.   }
  1251.  
  1252.   
  1253.   
  1254.   c->gl_visual = gl_create_visual(rgb_flag,
  1255.                                   GL_FALSE,    /* software alpha */
  1256.                                   db_flag,    /* db_flag */
  1257.                                   16,        /* depth_bits */
  1258.                                   8,        /* stencil_bits */
  1259.                                   8,        /* accum_bits */
  1260.                                   8,
  1261.                                   255.0, 255.0, 255.0, 255.0 );    
  1262.   
  1263.     if (!c->gl_visual) {
  1264.          return NULL;
  1265.       }
  1266.  
  1267.   /* allocate a new Mesa context */
  1268.   c->gl_ctx = gl_create_context( c->gl_visual, NULL,c);
  1269.  
  1270.   if (!c->gl_ctx) {
  1271.          gl_destroy_visual( c->gl_visual );
  1272.          free(c);
  1273.          return NULL;
  1274.       }
  1275.  
  1276.       c->gl_buffer = gl_create_framebuffer( c->gl_visual );
  1277.       if (!c->gl_buffer) {
  1278.          gl_destroy_visual( c->gl_visual );
  1279.          gl_destroy_context( c->gl_ctx );
  1280.          free(c);
  1281.          return NULL;
  1282.       }
  1283. //  setup_DD_pointers(c->gl_ctx);
  1284.  
  1285.   return c;
  1286. }
  1287.  
  1288.  
  1289.  
  1290. void /*APIENTRY*/ WMesaDestroyContext( void )
  1291. {
  1292.     WMesaContext c = Current;
  1293.     ReleaseDC(c->Window,c->hDC);
  1294.     WC = c;
  1295.  
  1296.     gl_destroy_visual( c->gl_visual );
  1297.     gl_destroy_framebuffer( c->gl_buffer );
  1298.     gl_destroy_context( c->gl_ctx );
  1299.  
  1300.     if (c->db_flag){
  1301.         wmDeleteBackingStore(c);
  1302.  
  1303. //Code added by Li Wei to enable parallel render
  1304. #if !defined(NO_STEREO)
  1305.         if(stereoBuffer==GL_TRUE){
  1306.             WMesaDestroyStereoBuffer();
  1307.             stereoBuffer=GL_FALSE;
  1308.         }
  1309. #endif 
  1310. // End modification
  1311.     }
  1312.     free( (void *) c );
  1313. //Code added by Li Wei to enable parallel render
  1314. // Parallel render only work in double buffer mode
  1315. #if !defined(NO_PARALLEL)
  1316.     if(parallelMachine)
  1317.         PRDestroyRenderBuffer();
  1318. #endif
  1319. // End modification
  1320. }
  1321.  
  1322.  
  1323.  
  1324. void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c )
  1325. {
  1326.     if(!c){
  1327.         Current = c;
  1328.         return;
  1329.     }
  1330.     
  1331.     //
  1332.     // A little optimization
  1333.     // If it already is current,
  1334.     // don't set it again
  1335.     //
  1336.     if(Current == c)
  1337.         return;
  1338.  
  1339.     //gl_set_context( c->gl_ctx );
  1340.     gl_make_current(c->gl_ctx, c->gl_buffer);
  1341.     Current = c;
  1342.     setup_DD_pointers(c->gl_ctx);
  1343.     if (Current->gl_ctx->Viewport.Width==0) {
  1344.       /* initialize viewport to window size */
  1345.       gl_Viewport( Current->gl_ctx,
  1346.                    0, 0, Current->width, Current->height );
  1347.     }
  1348. }
  1349.  
  1350.  
  1351.  
  1352. void /*APIENTRY*/ WMesaSwapBuffers( void )
  1353. {
  1354.   HDC DC = Current->hDC;
  1355.   if (Current->db_flag)
  1356.   {
  1357.     if (Current->rgb_flag)
  1358.         wmFlush(Current);
  1359.     else
  1360.       WinGBitBlt(DC,0,0,Current->width,Current->height,Current->dib.hDC,0,0);
  1361.   }
  1362. }
  1363.  
  1364.  
  1365.  
  1366. void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal)
  1367. {
  1368.   if (Current && Current->rgb_flag==GL_FALSE)
  1369.   {
  1370.     Current->hPal=Pal;
  1371.     GetPalette(Pal,Current->IndexFormat->bmiColors);
  1372.     WinGSetDIBColorTable(Current->dib.hDC,0,PAL_SIZE,Current->IndexFormat->bmiColors);
  1373.   }
  1374. }
  1375.  
  1376. //
  1377. // Free up the dib section that was created
  1378. //
  1379. BOOL wmDeleteBackingStore(PWMC pwc)
  1380. {
  1381.     SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
  1382.     DeleteDC(pwc->dib.hDC);
  1383.     DeleteObject(pwc->hbmDIB);
  1384.     UnmapViewOfFile(pwc->dib.base);
  1385.     CloseHandle(pwc->dib.hFileMap);
  1386.     return TRUE;
  1387. }
  1388.  
  1389.  
  1390. //
  1391. // This function creates the DIB section that is used for combined
  1392. // GL and GDI calls
  1393. //
  1394. BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
  1395. {
  1396.     HDC hdc = pwc->hDC;
  1397.     LPBITMAPINFO pbmi = &(pwc->bmi);
  1398.     int        iUsage;
  1399.  
  1400.     pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  1401.     pbmi->bmiHeader.biWidth = lxSize;
  1402.     pbmi->bmiHeader.biHeight= -lySize;
  1403.     pbmi->bmiHeader.biPlanes = 1;
  1404.     pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
  1405.     pbmi->bmiHeader.biCompression = BI_RGB;
  1406.     pbmi->bmiHeader.biSizeImage = 0;
  1407.     pbmi->bmiHeader.biXPelsPerMeter = 0;
  1408.     pbmi->bmiHeader.biYPelsPerMeter = 0;
  1409.     pbmi->bmiHeader.biClrUsed = 0;
  1410.     pbmi->bmiHeader.biClrImportant = 0;
  1411.  
  1412.     iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
  1413.  
  1414.     pwc->cColorBits = pbmi->bmiHeader.biBitCount;
  1415.     pwc->ScanWidth = lxSize;
  1416.  
  1417.     wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
  1418.  
  1419.     if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
  1420.         wmCreatePalette( pwc );
  1421.         wmSetDibColors( pwc );
  1422.     }
  1423.  
  1424.     return(TRUE);
  1425.  
  1426. }
  1427.  
  1428.  
  1429. //
  1430. // This function copies one scan line in a DIB section to another
  1431. //
  1432. BOOL WINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
  1433. {
  1434.     UINT uiScans = 0;
  1435.     LPBYTE    pDest = pwc->pbPixels;
  1436.     DWORD    dwNextScan = uiScanWidth;
  1437.     DWORD    dwNewScan = uiNewWidth;
  1438.     DWORD    dwScanWidth = (uiScanWidth * nBypp);
  1439.  
  1440.     //
  1441.     // We need to round up to the nearest DWORD
  1442.     // and multiply by the number of bytes per
  1443.     // pixel
  1444.     //
  1445.     dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
  1446.     dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
  1447.  
  1448.     for(uiScans = 0; uiScans < uiNumScans; uiScans++){
  1449.         CopyMemory(pDest, pBits, dwScanWidth);
  1450.         pBits += dwNextScan;
  1451.         pDest += dwNewScan;
  1452.     }
  1453.  
  1454.     return(TRUE);
  1455.  
  1456. }
  1457.  
  1458. BOOL WINAPI wmSetPixelFormat( PWMC pwdc, HDC hDC, DWORD dwFlags )
  1459. {
  1460.     return(TRUE);
  1461. }
  1462.  
  1463. static unsigned char threeto8[8] = {
  1464.     0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
  1465. };
  1466.  
  1467. static unsigned char twoto8[4] = {
  1468.     0, 0x55, 0xaa, 0xff
  1469. };
  1470.  
  1471. static unsigned char oneto8[2] = {
  1472.     0, 255
  1473. };
  1474.  
  1475. static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
  1476. {
  1477.     unsigned char val;
  1478.  
  1479.     val = i >> shift;
  1480.     switch (nbits) {
  1481.  
  1482.         case 1:
  1483.             val &= 0x1;
  1484.             return oneto8[val];
  1485.  
  1486.         case 2:
  1487.             val &= 0x3;
  1488.             return twoto8[val];
  1489.  
  1490.         case 3:
  1491.             val &= 0x7;
  1492.             return threeto8[val];
  1493.  
  1494.         default:
  1495.             return 0;
  1496.     }
  1497. }
  1498.  
  1499. void /*WINAPI*/ wmCreatePalette( PWMC pwdc )
  1500. {
  1501.     /* Create a compressed and re-expanded 3:3:2 palette */
  1502.       int            i;
  1503.     LOGPALETTE     *pPal;
  1504.     BYTE           rb, rs, gb, gs, bb, bs;
  1505.  
  1506.     pwdc->nColors = 0x100;
  1507.  
  1508.     pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
  1509.     memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
  1510.  
  1511.     pPal->palVersion = 0x300;
  1512.  
  1513.     rb = REDBITS;
  1514.     rs = REDSHIFT;
  1515.     gb = GREENBITS;
  1516.     gs = GREENSHIFT;
  1517.     bb = BLUEBITS;
  1518.     bs = BLUESHIFT;
  1519.  
  1520.     if (pwdc->db_flag) {
  1521.  
  1522.         /* Need to make two palettes: one for the screen DC and one for the DIB. */
  1523.         pPal->palNumEntries = pwdc->nColors;
  1524.         for (i = 0; i < pwdc->nColors; i++) {
  1525.             pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
  1526.             pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
  1527.             pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
  1528.             pPal->palPalEntry[i].peFlags = 0;
  1529.         }
  1530.         pwdc->hGLPalette = CreatePalette( pPal );
  1531.         pwdc->hPalette = CreatePalette( pPal );
  1532.     } 
  1533.  
  1534.     else {
  1535.         pPal->palNumEntries = pwdc->nColors;
  1536.         for (i = 0; i < pwdc->nColors; i++) {
  1537.             pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
  1538.             pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
  1539.             pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
  1540.             pPal->palPalEntry[i].peFlags = 0;
  1541.         }
  1542.         pwdc->hGLPalette = CreatePalette( pPal );
  1543.     }
  1544.     
  1545.     free(pPal);
  1546.  
  1547. }
  1548.  
  1549. //
  1550. // This function sets the color table of a DIB section
  1551. // to match that of the destination DC
  1552. //
  1553. BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)
  1554. {
  1555.     RGBQUAD            *pColTab, *pRGB;
  1556.     PALETTEENTRY    *pPal, *pPE;
  1557.     int                i, nColors;
  1558.     BOOL            bRet=TRUE;
  1559.     DWORD            dwErr=0;
  1560.  
  1561.     /* Build a color table in the DIB that maps to the
  1562.        selected palette in the DC.
  1563.     */
  1564.     nColors = 1 << pwc->cColorBits;
  1565.     pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
  1566.     memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
  1567.     GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
  1568.     pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
  1569.     for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
  1570.         pRGB->rgbRed = pPE->peRed;
  1571.         pRGB->rgbGreen = pPE->peGreen;
  1572.         pRGB->rgbBlue = pPE->peBlue;
  1573.     }
  1574.     if(pwc->db_flag)
  1575.         bRet = SetDIBColorTable(pwc->hDC, 0, nColors, pColTab );
  1576.  
  1577.     if(!bRet)
  1578.         dwErr = GetLastError();
  1579.  
  1580.     free( pColTab );
  1581.     free( pPal );
  1582.  
  1583.     return(bRet);
  1584. }
  1585.  
  1586. void /*WINAPI*/ wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
  1587. {
  1588.     if(Current->db_flag){
  1589.         LPBYTE    lpb = pwc->pbPixels;
  1590.         LPDWORD    lpdw;
  1591.         LPWORD    lpw;
  1592.         UINT    nBypp = pwc->cColorBits / 8;
  1593.         UINT    nOffset = iPixel % nBypp;
  1594.  
  1595.         // Move the pixel buffer pointer to the scanline that we
  1596.         // want to access
  1597.  
  1598.         pwc->dib.fFlushed = FALSE;
  1599.  
  1600.         lpb += pwc->ScanWidth * iScanLine;
  1601.         // Now move to the desired pixel
  1602.         lpb += iPixel * nBypp;
  1603.  
  1604.         lpdw = (LPDWORD)lpb;
  1605.         lpw = (LPWORD)lpb;
  1606.  
  1607.         if(nBypp == 2)
  1608.             *lpw = BGR16(r,g,b);
  1609.         else if (nBypp == 3){
  1610.             *lpdw = BGR24(r,g,b);
  1611.         }
  1612.         else
  1613.             *lpdw = BGR32(r,g,b);
  1614.     }
  1615.     else{
  1616.         HDC DC = DD_GETDC;
  1617.         SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));
  1618.         DD_RELEASEDC;
  1619.     }
  1620. }
  1621.  
  1622. void /*WINAPI*/ wmCreateDIBSection(
  1623.     HDC     hDC,
  1624.     PWMC pwc,    // handle of device context
  1625.     CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data
  1626.     UINT iUsage    // color data type indicator: RGB values or palette indices
  1627. )
  1628. {
  1629.     DWORD    dwSize = 0;
  1630.     DWORD    dwScanWidth;
  1631.     UINT    nBypp = pwc->cColorBits / 8;
  1632.     HDC        hic;
  1633.     
  1634.     dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
  1635.  
  1636.     pwc->ScanWidth = dwScanWidth;
  1637.  
  1638.     dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
  1639.  
  1640.     pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
  1641.                                           NULL,
  1642.                                           PAGE_READWRITE | SEC_COMMIT,
  1643.                                           0,
  1644.                                           dwSize,
  1645.                                           NULL);
  1646.  
  1647.     if (!pwc->dib.hFileMap)
  1648.         return;
  1649.  
  1650.     pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
  1651.                                   FILE_MAP_ALL_ACCESS,
  1652.                                   0,
  1653.                                   0,
  1654.                                   0);
  1655.  
  1656.     if(!pwc->dib.base){
  1657.         CloseHandle(pwc->dib.hFileMap);
  1658.         return;
  1659.     }
  1660.  
  1661.     pwc->pbPixels = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
  1662.     
  1663.     pwc->dib.hDC = CreateCompatibleDC(hDC);
  1664.  
  1665.     CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
  1666.  
  1667.     hic = CreateIC("display", NULL, NULL, NULL);
  1668.  
  1669. /*    pwc->hbmDIB = CreateDIBitmap(hic,
  1670.                          &(pwc->bmi.bmiHeader),
  1671.                          CBM_INIT,
  1672.                          pwc->pbPixels,
  1673.                          &(pwc->bmi),
  1674.                          DIB_RGB_COLORS);
  1675. */
  1676.   pwc->hbmDIB = CreateDIBSection(hic,
  1677.                         &(pwc->bmi.bmiHeader),
  1678.                         DIB_RGB_COLORS,
  1679.                         &(pwc->pbPixels),
  1680.                         pwc->dib.hFileMap,
  1681.                         0);
  1682.     pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
  1683.  
  1684.     DeleteDC(hic);
  1685.  
  1686.     return;
  1687.  
  1688. }
  1689.  
  1690. //
  1691. // Blit memory DC to screen DC
  1692. //
  1693. BOOL /*WINAPI*/ wmFlush(PWMC pwc)
  1694. {
  1695.     BOOL    bRet = 0;
  1696.     DWORD    dwErr = 0;
  1697.  
  1698.  
  1699. //    wmFlushBits(pwc);
  1700.  
  1701.     bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height, 
  1702.            pwc->dib.hDC, 0, 0, SRCCOPY);
  1703.  
  1704.     if(!bRet)
  1705.         dwErr = GetLastError();
  1706.  
  1707.     pwc->dib.fFlushed = TRUE;
  1708.  
  1709.     return(TRUE);
  1710.  
  1711. }
  1712.  
  1713.  
  1714. // The following code is added by Li Wei to enable stereo display
  1715.  
  1716. #if !defined(NO_STEREO)
  1717.  
  1718. void WMesaCreateStereoBuffer()
  1719. {
  1720.     /* Must use double buffer and not in parallelMode */
  1721.     if (! Current->db_flag 
  1722. #if !defined(NO_PARALLEL)
  1723.         || parallelFlag
  1724. #endif        
  1725.         )
  1726.         return;
  1727.  
  1728.     Buffer_Stereo = malloc( Current->ScanWidth * Current->height);
  1729.     ZeroMemory(Buffer_Stereo,Current->ScanWidth * Current->height);
  1730.     stereoBuffer = GL_TRUE ;
  1731. }
  1732.  
  1733. void WMesaDestroyStereoBuffer()
  1734. {
  1735.     /* Must use double buffer and not in parallelMode */
  1736.     if (! Current->db_flag 
  1737. #if !defined(NO_PARALLEL)
  1738.         || parallelFlag
  1739. #endif        
  1740.         )
  1741.         return;
  1742.     if(stereoBuffer){
  1743.         free(Buffer_Stereo);
  1744.         stereoBuffer = GL_FALSE ;
  1745.     }
  1746. }
  1747.  
  1748. void WMesaInterleave(GLenum aView)
  1749. {
  1750.     int offset;
  1751.     unsigned line;
  1752.     LPBYTE dest;
  1753.     LPBYTE src;
  1754.     if(aView == FIRST)
  1755.         offset = 0;
  1756.     else offset = 1;
  1757.  
  1758.     dest = Buffer_Stereo + offset * Current->ScanWidth;
  1759.     if(Current->rgb_flag )
  1760.         src = Current->pbPixels + Current->ScanWidth*(Current->height/2);
  1761.     else
  1762.         src = Current->ScreenMem;
  1763.  
  1764.     for(line = 0; line<Current->height/2; line ++){
  1765.         CopyMemory(dest, src, Current->ScanWidth);
  1766.         dest += 2*Current->ScanWidth;
  1767.         src += Current->ScanWidth;
  1768.     }
  1769.     if(aView == SECOND)
  1770.         if(Current->rgb_flag)
  1771.             CopyMemory(Current->pbPixels, Buffer_Stereo, Current->ScanWidth*Current->height);
  1772.         else
  1773.             CopyMemory(Current->ScreenMem, Buffer_Stereo, Current->ScanWidth*Current->height);
  1774. }
  1775.  
  1776. void WMesaShowStereo(GLuint list)
  1777. {
  1778.  
  1779.     GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
  1780.     GLfloat cm[16];
  1781.     // Must use double Buffer 
  1782.     if( ! Current-> db_flag )
  1783.         return;
  1784.  
  1785.     glViewport(0,0,Current->width,Current->height/2);
  1786.  
  1787.     glGetFloatv(GL_MODELVIEW_MATRIX,cm);
  1788.     glMatrixMode(GL_MODELVIEW);
  1789.     glLoadIdentity();
  1790.     gluLookAt(viewDistance/2,0.0,0.0 ,
  1791.              viewDistance/2,0.0,-1.0,
  1792.              0.0,1.0,0.0 );
  1793.     glMultMatrixf( cm );
  1794.     glMatrixMode(GL_MODELVIEW);
  1795.     glPushMatrix();
  1796.     glCallList( list );
  1797.     glPopMatrix();
  1798.     glFlush();
  1799.     WMesaInterleave( FIRST );
  1800.  
  1801.     glGetFloatv(GL_MODELVIEW_MATRIX,cm);
  1802.     glMatrixMode(GL_MODELVIEW);
  1803.     glLoadIdentity();
  1804.     gluLookAt(-viewDistance/2,0.0,0.0 ,
  1805.              -viewDistance/2,0.0,-1.0,
  1806.              0.0,1.0,0.0 );
  1807.     glMultMatrixf(cm);
  1808.     glMatrixMode(GL_MODELVIEW);
  1809.     glCallList(list);
  1810.     glFlush();
  1811.     WMesaInterleave( SECOND );
  1812.     glViewport(0,0,Current->width,Current->height);
  1813.     WMesaSwapBuffers();
  1814.  
  1815. }
  1816.  
  1817. void toggleStereoMode()
  1818. {
  1819.     if(!Current->db_flag)
  1820.         return;
  1821.     if(!stereo_flag){
  1822.         stereo_flag = 1;
  1823.         if(stereoBuffer==GL_FALSE)
  1824. #if !defined(NO_PARALLEL)
  1825.             if(!parallelFlag)
  1826. #endif
  1827.         {
  1828.             WMesaCreateStereoBuffer();
  1829.             }
  1830.     }
  1831.     else {
  1832.         stereo_flag = 0;
  1833.     if(stereoBuffer==GL_TRUE)
  1834. #if !defined(NO_PARALLEL)
  1835.         if(!parallelFlag)
  1836. #endif
  1837.             if(stereoBuffer==GL_TRUE){
  1838.                 WMesaDestroyStereoBuffer();
  1839.             }
  1840.     }
  1841. }
  1842.  
  1843. /* if in stereo mode, the following function is called */
  1844. void glShowStereo(GLuint list)
  1845. {
  1846.     WMesaShowStereo(list);
  1847. }
  1848.  
  1849. #endif // End if NO_STEREO not defined
  1850.  
  1851. #if !defined(NO_PARALLEL)
  1852.  
  1853. void toggleParallelMode(void)
  1854. {
  1855.     if(!parallelFlag){
  1856.         parallelFlag = GL_TRUE;
  1857.         if(parallelMachine==GL_FALSE){
  1858.                 PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
  1859.                                       Current->cColorBits/8,
  1860.                                       Current->width ,Current->height, 
  1861.                                       Current->ScanWidth,
  1862.                                       Current->rgb_flag? Current->pbPixels: Current->ScreenMem);
  1863.                 parallelMachine = GL_TRUE;
  1864.                 }
  1865.         }
  1866.     else {
  1867.         parallelFlag = GL_FALSE;
  1868.         if(parallelMachine==GL_TRUE){
  1869.                 PRDestroyRenderBuffer();
  1870.                 parallelMachine=GL_FALSE;
  1871.                 ReadyForNextFrame = GL_TRUE;
  1872.                 }
  1873.  
  1874. /***********************************************
  1875. // Seems something wrong!!!! 
  1876. ************************************************/
  1877.  
  1878.         WMesaMakeCurrent(Current);
  1879. #if !defined(NO_STEREO)
  1880.         stereo_flag = GL_FALSE ;
  1881. #endif
  1882.     }
  1883. }
  1884.  
  1885. void PRShowRenderResult(void)
  1886. {
  1887.     int flag = 0;
  1888. if(!glImageRendered())
  1889.         return;
  1890.  
  1891.   if (parallelFlag)
  1892.     {
  1893.       WMesaSwapBuffers();
  1894.      }
  1895.  
  1896. }
  1897. #endif //End if NO_PARALLEL not defined
  1898.  
  1899. //end modification
  1900.